package com.seguriapp.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Random;

import net.sf.json.JSONException;
import net.sf.json.JSONObject;

import org.apache.log4j.Logger;

import com.seguriapp.base.BaseEntity;

public class Util {

  private static final String DATE_FORMAT = "ddMMyyyy HH:mm:ss";
  public static final String PAGE_SIZE = "pageSize";
  public static final String PAGE = "page";
  public static final String COLUMN_SORT = "columnSort";
  public static final String ASCENDING = "ascending";
  public static final String FALSE = "false";
  public static final String TRUE = "true";
  public static final String SEPARATOR = ",";
  public static final String ALERT_JSON = "alert";
  public static final String COMPLAINT_JSON = "complaint";
  public static final String IMAGES_DIR = "/images/";
  public static final String VIDEOS_DIR = "/videos/";
  public static final String AUDIOS_DIR = "/audios/";

  private static final Logger LOGGER = Logger.getLogger(Util.class);

  public static String parseDateToString(final Date date) {
    SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
    if (date == null) {
      return "";
    } else {
      return sdf.format(date);
    }
  }

  public static Date parseStringToDate(final String dateStr) {
    SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
    if (dateStr != null) {
      try {
        return sdf.parse(dateStr);
      } catch (ParseException e) {
        return null;
      }
    }
    return null;
  }

  public static String parseEntityListToJson(final String listName, final List<? extends BaseEntity> list, final long totalPages) {
    final List<Map<?, ?>> l1 = new LinkedList<Map<?, ?>>();
    for (final BaseEntity entity : list) {
      l1.add(entity.toJsonString());
    }
    final JSONObject obj = new JSONObject();
    try {
      obj.put(listName, l1);
      obj.put("totalPages", totalPages);
    } catch (JSONException e) {
      LOGGER.error(e.getMessage(), e);
    }
    return obj.toString();
  }

  public static String parseEntityListToJson(final String listName, final List<? extends BaseEntity> list) {
    final List<Map<?, ?>> l1 = new LinkedList<Map<?, ?>>();
    for (final BaseEntity entity : list) {
      l1.add(entity.toJsonString());
    }
    final JSONObject obj = new JSONObject();
    try {
      obj.put(listName, l1);
    } catch (JSONException e) {
      LOGGER.error(e.getMessage(), e);
    }
    return obj.toString();
  }

  public static double distance(final double x1, final double y1, final double x2, final double y2) {
    final double dx = x1 - x2; // horizontal difference
    final double dy = y1 - y2; // vertical difference
    return Math.sqrt(dx * dx + dy * dy);
  }

  public static double distance(final double lat1, final double lon1, final double lat2, final double lon2, final char unit) {
    double theta = lon1 - lon2;
    double dist = Math.sin(deg2rad(lat1)) * Math.sin(deg2rad(lat2)) + Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * Math.cos(deg2rad(theta));
    dist = Math.acos(dist);
    dist = rad2deg(dist);
    dist = dist * 60 * 1.1515;
    if (unit == 'K') {
      dist = dist * 1.609344;
    } else if (unit == 'N') {
      dist = dist * 0.8684;
    }
    return (dist);
  }

  /**
   * This function converts decimal degrees to radians
   */
  private static double deg2rad(final double deg) {
    return (deg * Math.PI / 180.0);
  }

  /**
   * This function converts radians to decimal degrees
   */
  private static double rad2deg(final double rad) {
    return (rad * 180.0 / Math.PI);
  }

  /**
   * Gets a random alphanumeric string
   * 
   * @param length
   *          string length
   * @return random string
   */

  public static String randomString(int len) {
    final String ab = "0123456789abcdefghijklmnopqrstuvwxyz";
    final Random rnd = new Random();
    final StringBuilder sb = new StringBuilder(len);
    for (int i = 0; i < len; i++) {
      sb.append(ab.charAt(rnd.nextInt(ab.length())));
    }
    return sb.toString();
  }

}
